package main

import (
	"fmt"
	"sync"
	"time"
)

// Task represents a single task
type Task struct {
	ID       int
	Name     string
	Status   string
	Executor func()
}

// TaskManager manages tasks
type TaskManager struct {
	tasks     []*Task
	taskMutex sync.Mutex
	taskChan  chan *Task
}

// NewTaskManager creates a new TaskManager
func NewTaskManager() *TaskManager {
	return &TaskManager{
		tasks:    make([]*Task, 0),
		taskChan: make(chan *Task),
	}
}

// AddTask adds a new task to the manager
func (tm *TaskManager) AddTask(task *Task) {
	tm.taskMutex.Lock()
	defer tm.taskMutex.Unlock()

	tm.tasks = append(tm.tasks, task)
	tm.taskChan <- task
}

// RemoveTask removes a task from the manager
func (tm *TaskManager) RemoveTask(taskID int) {
	tm.taskMutex.Lock()
	defer tm.taskMutex.Unlock()

	for i, task := range tm.tasks {
		if task.ID == taskID {
			tm.tasks = append(tm.tasks[:i], tm.tasks[i+1:]...)
			break
		}
	}
}

// CancelTask cancels a task
func (tm *TaskManager) CancelTask(taskID int) {
	tm.taskMutex.Lock()
	defer tm.taskMutex.Unlock()

	for _, task := range tm.tasks {
		if task.ID == taskID {
			task.Status = "Cancelled"
			task.Executor = nil
			break
		}
	}
}

// ExecuteTasks executes all the tasks in the manager
func (tm *TaskManager) ExecuteTasks() {
	for task := range tm.taskChan {
		go func(t *Task) {
			t.Status = "Running"
			t.Executor()
			t.Status = "Completed"
		}(task)
	}
}

func main() {
	taskManager := NewTaskManager()

	// Start executing tasks
	go taskManager.ExecuteTasks()

	// Task 1: Print "Hello, World!"
	task1 := &Task{
		ID:   1,
		Name: "Print Hello, World!",
		Executor: func() {
			fmt.Println("Hello, World!")
		},
	}
	taskManager.AddTask(task1)

	// Task 2: Wait for 3 seconds and print a message
	task2 := &Task{
		ID:   2,
		Name: "Wait and Print",
		Executor: func() {
			time.Sleep(3 * time.Second)
			fmt.Println("Task completed after 3 seconds")
		},
	}
	taskManager.AddTask(task2)

	// Wait for tasks to complete
	time.Sleep(5 * time.Second)

	// Add a new task dynamically
	task3 := &Task{
		ID:   3,
		Name: "Dynamic Task",
		Executor: func() {
			fmt.Println("This is a dynamically added task")
		},
	}
	taskManager.AddTask(task3)

	// Wait for tasks to complete
	time.Sleep(5 * time.Second)
}
